﻿using org.xisoft.game.utils.ui;
using System.Drawing;
using System.IO;

namespace org.xisoft.game.utils.game
{
    public abstract class ChessBoardPanelBase
    {
        public ChessBoardControl ChessBoardControl { get; set; }

        public abstract void Read(BinaryReader br);
        public abstract void Save(BinaryWriter bw);

        protected int MaxX { get; private set; }
        protected int MaxY { get; private set; }
        public ChessBoardPanelBase(int maxX, int maxY)
        {
            MaxX = maxX;
            MaxY = maxY;

            Color writeItemColor = Color.Red;
            Color blackItemColor = Color.Black;
            pen = Pens.Black;
            broadPen = Pens.Blue;
            broadFontBrush = Brushes.Blue;
            writeItemBrush = new SolidBrush(writeItemColor);
            blackItemBrush = new SolidBrush(blackItemColor);
            writeItemPen = new Pen(writeItemColor);
            blackItemPen = new Pen(blackItemColor);
        }


        private readonly Pen pen;
        protected readonly Pen broadPen;
        protected readonly Brush broadFontBrush;
        protected readonly Brush writeItemBrush;
        protected readonly Brush blackItemBrush;
        protected readonly Pen writeItemPen;
        protected readonly Pen blackItemPen;
        protected readonly Pen selectedItemPen = Pens.IndianRed;

        /// <summary>
        /// 网格的高宽
        /// </summary>
        private int gridItemWidth, gridItemHeight;

        protected int GridItemWidth { get { return gridItemWidth; } }

        protected int GridItemHeight { get { return gridItemHeight; } }

        /// <summary>
        /// 棋子的宽
        /// </summary>
        private int itemWidth, itemHeight;

        protected int ItemWidth { get { return itemWidth; } }
        protected int ItemHeight { get { return itemHeight; } }



        protected virtual void DrawChessBoardRow(Graphics g, int index, int left, int top, int width)
        {
            g.DrawLine(broadPen, left, top, width + left, top);
        }

        protected virtual void DrawChessBoardCol(Graphics g, int index, int left, int top, int height)
        {
            g.DrawLine(broadPen, left, top, left, height + top);
        }

        /// <summary>
        /// 画棋盘
        /// </summary>
        /// <param name="g"></param>
        /// <param name="rect"></param>
        protected virtual void DrawChessBoard(Graphics g, Rectangle rect)
        {
            g.DrawRectangle(pen, rect);
            g.DrawRectangle(pen, rect.Left - 2, rect.Top - 2, rect.Width + 4, rect.Height + 4);


            int width = rect.Width;
            int height = rect.Height;

            for (int i = 0; i < MaxX; i++)
            {
                int top = GridItemHeight * i + rect.Top;
                DrawChessBoardRow(g, i, rect.Left, top, width);
            }
            for (int i = 0; i < MaxY; i++)
            {
                int left = GridItemWidth * i + rect.Left;
                DrawChessBoardCol(g, i, left, rect.Top, height);
            }
        }

        protected virtual void DrawItems(Graphics g, Rectangle rect)
        {

        }



        private Rectangle rect;

        protected virtual Rectangle CalcRectangle(int left, int top, int width, int height)
        {
            int w = MaxX - 1;
            int h = MaxY - 1;

            int newWidth = width / w * w;
            int newHeight = height / h * h;


            gridItemWidth = newWidth / w;
            gridItemHeight = newHeight / h;

            itemWidth = GridItemWidth * 7 / 12;
            itemHeight = GridItemHeight * 7 / 12;

            return new Rectangle(left, top, newWidth, newHeight);
        }

        protected Rectangle Rect { get { return rect; } }
        public void OnPaint(Graphics g)
        {
            int padding = 40;


            int width = (ChessBoardControl.Width - padding);
            int height = (ChessBoardControl.Height - padding);
            rect = CalcRectangle(padding - 15, padding - 15, width, height);


            DrawChessBoard(g, rect);
            DrawItems(g, rect);
        }

        public abstract void OnMouseClick(int mouseX, int mouseY);

        public abstract void Undo();


        protected Font Font { get { return ChessBoardControl.Font; } }

        public abstract string Name { get; }

        protected void Invalidate()
        {
            ChessBoardControl.Invalidate();
        }

        protected void ShowLoading()
        {
            ChessBoardControl.ShowLoading(true);
        }

        protected void HideLoading()
        {
            ChessBoardControl.ShowLoading(false);
        }

    }
}
